package com.corechina.apex_osswords.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.corechina.apex_osswords.common.InvertCodeGeneratorUtil;
import com.corechina.apex_osswords.common.Response;
import com.corechina.apex_osswords.common.ShiroUtils;
import com.corechina.apex_osswords.common.WeiXinUserUtils;
import com.corechina.apex_osswords.domain.dao.*;
import com.corechina.apex_osswords.domain.dto.CoreClienteleDto;
import com.corechina.apex_osswords.domain.dto.CoreProjectDto;
import com.corechina.apex_osswords.domain.entity.*;
import com.corechina.apex_osswords.domain.vo.CoreProjectVo;
import com.corechina.apex_osswords.domain.vo.ProjectStatistics;
import com.corechina.apex_osswords.service.ICoreProjectService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 * 项目信息表 服务实现类
 * </p>
 *
 * @author cc
 * @since 2022-03-11
 */
@Service
public class CoreProjectServiceImpl extends ServiceImpl<CoreProjectMapper, CoreProject> implements ICoreProjectService {

    @Autowired
    private CoreProjectMapper coreProjectMapper;

    @Autowired
    private CoreProjectMapper corePlaceMapper;


    @Autowired
    private CoreProjectUserMapper coreProjectUserMapper;

    @Autowired
    private CoreWorkOrderMapper coreWorkOrderMapper;

    @Autowired
    private CoreMaintenanceEngineerMapper coreMaintenanceEngineerMapper;

    @Autowired
    private CoreEnterpriseEngineerMapper coreEnterpriseEngineerMapper;

    @Autowired
    private CoreEnterpriseMapper coreEnterpriseMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Response add(CoreProjectDto coreProjectDto) {
        CoreProject coreProject = new CoreProject();
        BeanUtils.copyProperties(coreProjectDto, coreProject);
        coreProject.setProjectCode(this.getCode());
        coreProject.setSerialNumber(this.getSerialNumber(ShiroUtils.getEnterpriseId()));
        coreProject.setEnterpriseId(ShiroUtils.getEnterpriseId());
        //    coreProjectDto.setServiceId(coreProject.getServiceId());
        coreProjectMapper.insert(coreProject);
        if (coreProjectDto.getEngineerIds() != null) {
            this.addProjectUser(coreProjectDto.getEngineerIds(), coreProject.getId());
        }
        return Response.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response update(CoreProjectDto coreProjectDto) {
        CoreProject coreProject = new CoreProject();
        BeanUtils.copyProperties(coreProjectDto, coreProject);
        coreProjectMapper.updateById(coreProject);
        QueryWrapper<CoreProjectUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("project_id", coreProjectDto.getId());
        coreProjectUserMapper.delete(queryWrapper);
        if (coreProjectDto.getEngineerIds() != null) {
            this.addProjectUser(coreProjectDto.getEngineerIds(), coreProject.getId());
        }
        return Response.ok();
    }

    private void addProjectUser(List<Integer> ids, Integer projectId) {
        CoreProjectUser coreProjectUser = new CoreProjectUser();
        coreProjectUser.setProjectId(projectId);
        for (Integer userId : ids) {
            coreProjectUser.setUserId(userId);
            coreProjectUserMapper.insert(coreProjectUser);
        }
    }

    public String getSerialNumber(Integer enterpriseId) {
        String serialNumber = coreProjectMapper.getMaxSerialNumber(enterpriseId);
        CoreEnterprise coreEnterprise = coreEnterpriseMapper.selectById(enterpriseId);
        if (serialNumber == null || !serialNumber.contains(coreEnterprise.getSerialNumber())) {
            return coreEnterprise.getSerialNumber() + "-" + "P001";
        }
        serialNumber = StringUtils.substringAfter(serialNumber, "P");
        serialNumber = coreEnterprise.getSerialNumber() + "-P" + String.format("%03d", Integer.parseInt(serialNumber) + 1);
        QueryWrapper<CoreProject> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("serial_number", serialNumber).eq("enterprise_id", enterpriseId);
        if (coreProjectMapper.selectCount(queryWrapper) > 0) {
            serialNumber = getSerialNumber(enterpriseId);
        }
        return serialNumber;
    }

    public String getCode() {
        String code = InvertCodeGeneratorUtil.genCodes(6, 1).get(0).toUpperCase();
        QueryWrapper<CoreProject> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("project_code", code);
        if (coreProjectMapper.selectCount(queryWrapper) > 0) {
            code = getCode();
        }
        return code;
    }

    @Override
    public Response getOne(Integer id) {
        CoreProjectVo coreProjectVo = coreProjectMapper.getOne(id);
        coreProjectVo.setCanRepairs(1);
        return Response.ok(coreProjectVo);
    }

    @Override
    public Response getOneForRepairs(Integer id) {
        CoreProjectVo coreProjectVo = coreProjectMapper.getOneForRepairs(id);
        coreProjectVo.setCanRepairs(0);
        return Response.ok(coreProjectVo);
    }

    @Override
    public Response getList(Integer projectType, Integer serviceId, String projectName, String serviceBeginDate, String serviceEndDate, Integer pageIndex, Integer pageSize) {
        IPage<CoreProjectVo> projectVoIPage = coreProjectMapper.getList(new Page(pageIndex, pageSize), projectType, projectName, serviceId, serviceBeginDate, serviceEndDate, ShiroUtils.getSeeAll() == 1 ? null : ShiroUtils.getEnterpriseId());
        return Response.ok(projectVoIPage.getRecords(), projectVoIPage.getTotal());
    }

    @Override
    public Response getListForWeiXin(Integer type, Integer projectType, Integer serviceId, Integer pageIndex, Integer pageSize) {
        IPage<CoreProjectVo> projectVoIPage;
        if (type == 1) {
            projectVoIPage = coreProjectMapper.getListForWeiXin(new Page(pageIndex, pageSize), WeiXinUserUtils.getUserId(), 1, projectType, serviceId, WeiXinUserUtils.getEnterpriseId());
        } else {
            projectVoIPage = coreProjectMapper.getListForWeiXin(new Page(pageIndex, pageSize), null, null, projectType, serviceId, null);
        }
        return Response.ok(projectVoIPage.getRecords(), projectVoIPage.getTotal());
    }

    @Override
    public Response getProjectCount() {
        ProjectStatistics projectStatistics = new ProjectStatistics();
        ProjectStatistics projectStatistics2 = coreWorkOrderMapper.getOrderCount(WeiXinUserUtils.getUserId(), null, WeiXinUserUtils.getEnterpriseId());
        if (projectStatistics2 != null) {
            BeanUtils.copyProperties(projectStatistics2, projectStatistics);
        }
        projectStatistics.setProjectCount(coreProjectMapper.getProjectCount(WeiXinUserUtils.getUserId(), WeiXinUserUtils.getEnterpriseId()));
        projectStatistics.setEquipmentCount(coreProjectMapper.getEquipmentCount(WeiXinUserUtils.getUserId()));
        return Response.ok(projectStatistics);
    }

    @Override
    public Response delete(Integer id) {
        coreProjectMapper.updateIsDel(id);
        return Response.ok();
    }

    @Override
    public Response addClientele(CoreClienteleDto coreClienteleDto) {
        if (coreMaintenanceEngineerMapper.selectCount(new QueryWrapper<CoreMaintenanceEngineer>().eq("tel", coreClienteleDto.getTel())) > 0) {
            return Response.error("该手机号人员已添加，请勿重复添加");
        }

        CoreMaintenanceEngineer coreMaintenanceEngineer = new CoreMaintenanceEngineer();
        BeanUtils.copyProperties(coreClienteleDto, coreMaintenanceEngineer);
        coreMaintenanceEngineer.setEngineerType(2);
        coreMaintenanceEngineerMapper.insert(coreMaintenanceEngineer);

        CoreProjectUser coreProjectUser = new CoreProjectUser();
        coreProjectUser.setProjectId(coreClienteleDto.getProjectId());
        coreProjectUser.setUserId(coreMaintenanceEngineer.getId());
        coreProjectUserMapper.insert(coreProjectUser);

        CoreEnterpriseEngineer coreEnterpriseEngineer = new CoreEnterpriseEngineer();
        coreEnterpriseEngineer.setEngineerId(coreMaintenanceEngineer.getId());
        coreEnterpriseEngineer.setEnterpriseId(ShiroUtils.getEnterpriseId());
        coreEnterpriseEngineerMapper.insert(coreEnterpriseEngineer);
        return Response.ok();
    }

    @Override
    public Response getEquipmentCount() {
        ProjectStatistics projectStatistics = new ProjectStatistics();
        projectStatistics.setEquipmentCount(coreProjectMapper.getEquipmentCount(WeiXinUserUtils.getUserId()));
        return Response.ok(projectStatistics);
    }

    @Override
    public CoreProject getOneBySerialNumber(String serialNumber) {
        return coreProjectMapper.getOneBySerialNumber(serialNumber);
    }
}
